package com.hjz.main;

import com.hjz.pojo.Person;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toMap;

/**
 * Created by huangjz on 2017/6/14.
 */
public class Demo1 {

    public static void main(String[] args) {
//        listDemo();
//        listDemo2();
//        classDemo1();
//        classDemo2();

//        sortDemo1();
//        sortDemo2();
//        sortDemo3();

//        streamDemo1();
        streamDemo2();
//        streamDemo3();


    }

    private static void streamDemo3() {
        List<Person> javaProgrammers = new ArrayList<Person>() {
            {
                add(new Person("Sindy", "Jonie", "Java programmer", "female", 32, 1600));
                add(new Person("Vere", "Hervey", "Java programmer", "male", 22, 1200));
                add(new Person("Maude", "Jaimie", "Java programmer", "female", 27, 1900));
                add(new Person("Shawn", "Randall", "Java programmer", "male", 30, 2300));
                add(new Person("Jayden", "Corrina", "Java programmer", "female", 35, 1700));
                add(new Person("Palmer", "Dene", "Java programmer", "male", 33, 2000));
                add(new Person("Addison", "Pam", "Java programmer", "female", 34, 1300));
            }
        };
        List<Person> phpProgrammers = new ArrayList<Person>() {
            {
                add(new Person("Tori", "Sheryl", "PHP programmer", "female", 21, 1000));
                add(new Person("Osborne", "Shad", "PHP programmer", "male", 32, 1100));
                add(new Person("Rosalind", "Layla", "PHP programmer", "female", 25, 1300));
                add(new Person("Fraser", "Hewie", "PHP programmer", "male", 36, 1100));
                add(new Person("Quinn", "Tamara", "PHP programmer", "female", 21, 1000));
                add(new Person("Alvin", "Lance", "PHP programmer", "male", 38, 1600));
                add(new Person("Evonne", "Shari", "PHP programmer", "female", 40, 1800));
            }
        };

//        double sumMoney = javaProgrammers
//                .parallelStream()
//                .mapToDouble(Person::getSalary)
//                .sum();
//        System.out.println("java工资总和："+sumMoney);

        //summaryStatistics方法获得stream 中元素的各种汇总数据
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        IntSummaryStatistics stats = numbers
                .stream()
                .mapToInt(x -> x)
                .summaryStatistics();
        System.out.println("List中最大的数字 : " + stats.getMax());
        System.out.println("List中最小的数字 : " + stats.getMin());
        System.out.println("所有数字的总和   : " + stats.getSum());
        System.out.println("所有数字的平均值 : " + stats.getAverage());
    }

    private static void streamDemo2() {
        List<Person> javaProgrammers = new ArrayList<Person>() {
            {
                add(new Person("Floyd", "Donny", "Java programmer", "male", 33, 1800));
                add(new Person("Sindy", "Jonie", "Java programmer", "female", 32, 1600));
                add(new Person("Vere", "Hervey", "Java programmer", "male", 22, 1200));
                add(new Person("Maude", "Jaimie", "Java programmer", "female", 27, 1900));
                add(new Person("Shawn", "Randall", "Java programmer", "male", 30, 2300));
                add(new Person("Jayden", "Corrina", "Java programmer", "female", 35, 1700));
                add(new Person("Palmer", "Dene", "Java programmer", "male", 33, 2000));
                add(new Person("Addison", "Pam", "Java programmer", "female", 34, 1300));
            }
        };

        List<Person> phpProgrammers = new ArrayList<Person>() {
            {
                add(new Person("Victor", "Channing", "PHP programmer", "male", 32, 1600));
                add(new Person("Tori", "Sheryl", "PHP programmer", "female", 21, 1000));
                add(new Person("Osborne", "Shad", "PHP programmer", "male", 32, 1100));
                add(new Person("Rosalind", "Layla", "PHP programmer", "female", 25, 1300));
                add(new Person("Fraser", "Hewie", "PHP programmer", "male", 36, 1100));
                add(new Person("Quinn", "Tamara", "PHP programmer", "female", 21, 1000));
                add(new Person("Alvin", "Lance", "PHP programmer", "male", 38, 1600));
                add(new Person("Evonne", "Shari", "PHP programmer", "female", 40, 1800));
            }
        };

        //map是一个对于流对象的中间操作，通过给定的方法，它能够把流对象中的每一个元素对应到另外一个对象上
        //不影响原来的集合
//        phpProgrammers
//                .stream()
//                .map(Person::getFirstName)
//                .forEach(System.out::println);

        //collect拼接
        String s = phpProgrammers
                .stream()
                .map(Person::getFirstName)
                .collect(joining(";"));
        System.out.println("拼接："+s);

        TreeSet<String> treeset = phpProgrammers
                .stream()
                .map(Person::getFirstName)
//                .collect(Collectors.toSet());
                .collect(Collectors.toCollection(TreeSet::new));

        //TODO
//        Map<Integer, String> map = phpProgrammers
//                .stream()
//                .collect(Collectors.toMap(Person::getAge, Person::getLastName));
    }

    private static void streamDemo1() {
        /**使用Lambdas和Streams
         Stream是对集合的包装,通常和lambda一起使用。 使用lambdas可以支持许多操作,
         如 map, filter, limit, sorted, count, min, max, sum, collect 等等。
         同样,Stream使用懒运算,他们并不会真正地读取所有数据,遇到像getFirst() 这样的方法就会结束链式语法。*/
        List<Person> javaProgrammers = new ArrayList<Person>() {
            {
                add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 43, 2000));
                add(new Person("Tamsen", "Brittany", "Java programmer", "female", 23, 1500));
                add(new Person("Floyd", "Donny", "Java programmer", "male", 33, 1800));
                add(new Person("Sindy", "Jonie", "Java programmer", "female", 32, 1600));
                add(new Person("Vere", "Hervey", "Java programmer", "male", 22, 1200));
                add(new Person("Maude", "Jaimie", "Java programmer", "female", 27, 1900));
                add(new Person("Shawn", "Randall", "Java programmer", "male", 30, 2300));
                add(new Person("Jayden", "Corrina", "Java programmer", "female", 35, 1700));
                add(new Person("Palmer", "Dene", "Java programmer", "male", 33, 2000));
                add(new Person("Addison", "Pam", "Java programmer", "female", 34, 1300));
            }
        };

        List<Person> phpProgrammers = new ArrayList<Person>() {
            {
                add(new Person("Jarrod", "Pace", "PHP programmer", "male", 34, 1550));
                add(new Person("Clarette", "Cicely", "PHP programmer", "female", 23, 1200));
                add(new Person("Victor", "Channing", "PHP programmer", "male", 32, 1600));
                add(new Person("Tori", "Sheryl", "PHP programmer", "female", 21, 1000));
                add(new Person("Osborne", "Shad", "PHP programmer", "male", 32, 1100));
                add(new Person("Rosalind", "Layla", "PHP programmer", "female", 25, 1300));
                add(new Person("Fraser", "Hewie", "PHP programmer", "male", 36, 1100));
                add(new Person("Quinn", "Tamara", "PHP programmer", "female", 21, 1000));
                add(new Person("Alvin", "Lance", "PHP programmer", "male", 38, 1600));
                add(new Person("Evonne", "Shari", "PHP programmer", "female", 40, 1800));
            }
        };

//        System.out.println("所有程序员的姓名：");
//        javaProgrammers.forEach(person -> System.out.printf("%s %s \n",person.getFirstName(),person.getLastName()));

//        System.out.println("给程序员加薪5%");
//        //Consumer<T> 代表了接受一个输入参数并且无返回的操作 method
        Consumer<Person> giveRaise = person -> person.setSalary(person.getSalary() * 1.05);
        javaProgrammers.forEach(giveRaise);
        javaProgrammers.forEach(person -> System.out.println(person.getSalary()));

        /**过滤器filter()*/
//        System.out.println("下面是月薪超过 $1,400 的PHP程序员:");
//        phpProgrammers.stream()
//                .filter(person -> person.getSalary()>1400)
//                .forEach(person -> System.out.printf("%s %s \n",person.getFirstName(),person.getLastName()));

//        System.out.println("下面是年龄大于 24岁且月薪在$1,400以上的女PHP程序员:");
        //定义filter
        //Predicate<T> 接受一个输入参数，返回一个布尔值结果。
        Predicate<Person> ageFilter=person -> person.getAge()>24;
        Predicate<Person> sexFilter=person -> "female".equals(person.getSex());
        Predicate<Person> salaryFilter=person -> person.getSalary()>1400;
        phpProgrammers.stream()
                .filter(ageFilter)
                .filter(sexFilter)
                .filter(salaryFilter)
                .forEach(person -> System.out.printf("%s %s;", person.getFirstName(), person.getLastName()));

        //使用limit方法,可以限制结果集的个数:
        System.out.println("最前面的3个女 Java programmers:");
        javaProgrammers.stream()
                .filter(sexFilter)
                .limit(3)
                .forEach(person -> System.out.printf("%s %s;",person.getFirstName(),person.getLastName()));

        //使用sorted方法排序
//        System.out.println("根据name排序");
//        List<Person> sortedNameList=javaProgrammers
//                .stream()
////                .sorted((p1,p2)->p1.getFirstName().compareTo(p2.getFirstName()))
//                .sorted((p1,p2)->p1.getAge()-p2.getAge())
//                .limit(5)
//                .collect(toList());
//        sortedNameList.forEach(person -> System.out.printf("%s %s %n", person.getFirstName(), person.getLastName()));

        //最低或最高
//        System.out.println("年龄最大的 java programer");
//        Person person = javaProgrammers
//                .stream()
//                .max((p1, p2) -> p1.getAge() - p2.getAge())
//                .get();
//        System.out.printf("%s %d",person.getFirstName(),person.getAge());

    }

    private static void sortDemo3() {
        String[] players = {"junzhe huang", "qichang cai", "yaojing xiao", "yao yao", "miss chung"};
//        Arrays.sort(players, new Comparator<String>() {
//            @Override
//            public int compare(String o1, String o2) {
//                return (o1.substring(o1.indexOf(" ")+1).compareTo(o2.substring(o2.indexOf(" ")+1)));
//            }
//        });

        Arrays.sort(players, (String s1, String s2) -> (s1.substring(s1.indexOf(" ") + 1).compareTo(s2.substring(s2.indexOf(" ") + 1))));

        for (String str :
                players) {
            System.out.println(str);
        }
    }

    private static void sortDemo2() {
        String[] players = {"bbb", "aaa", "gggg", "fff", "ccc"};
        Arrays.sort(players, (String::compareTo));
        for (String str :
                players) {
            System.out.println(str);
        }
    }

    private static void sortDemo1() {
        String[] players = {"junzhe huang", "qichang cai", "yaojing xiao", "yao yao", "miss chung"};
//        Arrays.sort(players, new Comparator<String>() {
//            @Override
//            public int compare(String o1, String o2) {
//                return o1.compareTo(o2);
//            }
//        });

//        Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));
//        Arrays.sort(players,sortByName);

        Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));

        for (String str :
                players) {
            System.out.println(str);
        }
    }

    private static void classDemo2() {
        Runnable race1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("race1");
            }
        };

        Runnable race2 = () -> System.out.println("hehe");
        race1.run();
        race2.run();
    }

    private static void classDemo1() {
        //        new Thread(new Runnable() {
//            @Override
//            public void run() {
//
//            }
//        });
//        try {
//            Thread.currentThread().sleep(10000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        new Thread(() -> System.out.println("helloworld")).start();
    }

    private static void listDemo2() {
        String[] atp = {"1", "22", "333", "44444"};
        List<String> players = Arrays.asList(atp);

        players.forEach(System.out::println);
    }

    private static void listDemo() {
        String[] atp = {"1", "22", "333", "44444"};
        List<String> players = Arrays.asList(atp);

//        for (String str :
//                players) {
//            System.out.println(str);
//        }

        players.forEach((player) -> System.out.print(player + "; "));
    }


}
